#pragma once

#include <string>
#include <utility>
#include <memory>
#include <system_error>

#include "helper/iter/Iterator.h"

namespace memdb {

class ITable {
public:

  typedef std::string KeyType;
  typedef std::string ValueType;

  typedef std::pair<const KeyType, ValueType> * Item;
  typedef helper::iter::Iterator<Item> Iterator;

  virtual ~ITable(){}

  virtual bool exists(const KeyType & key) const {
    std::string value;
    return std::error_code() == this->get(key, value);
  }

  virtual std::error_code get(const KeyType & key, std::string & value) const = 0;
  virtual std::error_code insert(const KeyType & key, const KeyType & value) = 0;
  virtual std::error_code remove(const KeyType & key) = 0;

  virtual std::error_code update(const KeyType & key, const KeyType & value) = 0;
  virtual std::error_code replace(const KeyType & key, const KeyType & value) = 0;

  virtual std::error_code update(const KeyType & key, const KeyType & value, std::string & old) = 0;
  virtual std::pair<std::error_code, bool> replace(const KeyType & key, const KeyType & value, std::string & old) = 0;

  virtual size_t count() const = 0;

  virtual std::unique_ptr<Iterator> iterator() const = 0;
  virtual std::unique_ptr<Iterator> range(size_t offset, size_t len) const = 0;
  virtual std::unique_ptr<Iterator> findRange(const KeyType & key, size_t offset, size_t len) const = 0;
};

}//namespace memdb 


#include <optional>

namespace memdb {

class ITables {
public:
  typedef std::string KeyType;
  typedef ITable* ValueType;

  typedef std::pair<const KeyType, ValueType> * Item;
  typedef helper::iter::Iterator<Item> Iterator;

  virtual ~ITables(){};

	virtual std::pair<std::error_code, ValueType> create(const KeyType & name) = 0;
  virtual std::error_code drop(const KeyType & name) = 0;
	virtual bool exists(const KeyType & name) const = 0;
  virtual std::optional<ValueType> get(const KeyType & name) const = 0;

  virtual size_t count() const = 0;

  virtual std::unique_ptr<Iterator> iterator() const = 0;
private:
};
}//namespace memdb 


#include "helper/resource/IOpenable.h"
#include "helper/resource/IResource.h"

namespace memdb {
class IDB : public helper::resource::IResource<std::error_code> 
					, public helper::resource::IOpenable<std::error_code>{
public:
	virtual ~IDB(){}			

  virtual ITables & tables() const = 0;
};

}//namespace memdb


